/* 
 * File:   StackListCommand.h
 * Author: Gab'z
 *
 * Created on 5 juin 2012, 10:59
 */

#ifndef STACKLISTCOMMAND_H
#define	STACKLISTCOMMAND_H

#include "../UndoableRedoableCommand.h"

namespace calculator {
    class StackList;

    class StackListCommand : public UndoableRedoableCommand {
    public:

        /**
         * Vérifie si la commande est exécutable.
         * Méthode virtuelle pure appelée avant execute() afin de 
         * vérifier les paramètres et l'état des piles. @see Parameters, StackList, Stack
         * @return une std::string vide si la commande est exécutable,
         * sinon renvoie soit la raison de l'erreur dans la plupart des cas.
         */
        virtual std::string isExecutable() const = 0;

        /**
         * Méthode d'entrée du Design Pattern Command.
         * Utilisation avec le Design Pattern Template Method, appelle la méthode
         * apply(StackList* stacklist), une StackListCommand ayant pour but de gérer l'ensemble des Stack
         */
        void execute() const throw (CommandException);

        /**
         * Clone la commande.
         * On ne peut pas créer de commandes (sauf des constantes) directement,
         * c'est le rôle du CommandManager, on a cependant besoin de les copier
         * pour les sauvegardes et la fonction UNDO/REDO.
         * @return une copie de la commande.
         */
        virtual StackListCommand* clone() const = 0;

        /**
         * Destructeur de StackListCommand.
         */
        virtual ~StackListCommand();

    protected:

        /**
         * Crée un Memento propre à chaque Command contenant une copie
         * des données qui vont être modifiées.
         * @return un Memento spécialisé.
         */
        virtual const Memento* createMemento() const throw (CommandException) = 0;

        /**
         * Restaure le Context dans l'état précédent l'exécution de la commande.
         * Le comportement de base de cette méthode est de vider la pile 
         * courante pour y remettre celle sauvegardée
         * On suppose que le Memento utilisé est un StackMemento, sinon le
         * comportement de cette fonction doit aussi être redéfini.
         * Si ce n'est pas fait, on lève une MementoException.
         * @param memento le Memento contenant les données à restituer.
         */
        virtual void restoreFromMemento(const Memento* memento) const throw (MementoException) = 0;

        /**
         * Méthode appelée par execute() via un Template Method.
         * @param stacklist la liste de Stack sur laquelle on applique la commande.
         */
        virtual void apply(StackList* stacklist) const throw (CommandException) = 0;

        /**
         * Constructeur de StackListCommand.
         * Chaque StackListCommand est défini par son nom. @see UndoableRedoableCommand
         * @param name le nom de la commande.
         */
        StackListCommand(const std::string name);
    };
}


#endif	/* STACKLISTCOMMAND_H */

